﻿using System;
using System.Collections;

namespace jsonar
{
	/// <summary>
	/// JSON基类
	/// </summary>
	public abstract class Json
	{
		public readonly static Json NULL = Null.INSTANCE;
		public readonly static Json TRUE = True.INSTANCE;
		public readonly static Json FALSE = False.INSTANCE;

		public static Json GetJson(Json obj) { return obj; }
		public static Json GetJson(int obj) { return new Int(obj); }
		public static Json GetJson(long obj) { return new Long(obj); }
		public static Json GetJson(float obj) { return new Float(obj); }
		public static Json GetJson(double obj) { return new Double(obj); }
		public static Json GetJson(decimal obj) { return new Decimal(obj); }
		public static Json GetJson(bool obj) { if (obj) return True.INSTANCE; return False.INSTANCE; }
		public static Json GetJson(DateTime obj) { return new String(obj.ToString("yyyy/MM/dd HH:mm:ss")); }
		public static Json GetJson(string obj) { if (obj == null) return Null.INSTANCE; return new String(obj); }
		public static Json GetJson(IConvertible obj)
		{
			try { return new Double(obj.ToDouble(null)); } catch { return new String(obj.ToString(null)); }
		}

		/// <summary>
		/// 获取json对象
		/// </summary>
		/// <param name="obj"></param>
		/// <param name="deep">对object的解析深度，0不解析</param>
		/// <returns></returns>
		public static Json GetJson(IEnumerable obj, int deep)
		{
			if (obj == null) return Null.INSTANCE;
			if (deep < 0) return new String(obj.ToString());

			if (obj is IDictionary)
			{
				IDictionaryEnumerator emdict = ((IDictionary)obj).GetEnumerator();
				if (emdict == null) return Null.INSTANCE;
				Obj dict = new Obj(10);
				while (emdict.MoveNext())
				{
					if (emdict.Key == null) continue;
					dict.Add(emdict.Key.ToString(), GetJson(emdict.Value, deep));
				}
				return dict;
			}

			IEnumerator em = ((IEnumerable)obj).GetEnumerator();
			if (em == null) return Null.INSTANCE;
			if (em is IDictionaryEnumerator) {
				Obj dict = new Obj(10);
				IDictionaryEnumerator emdict = em as IDictionaryEnumerator;
				while (emdict.MoveNext())
				{
					if (emdict.Key == null) continue;
					dict.Add(emdict.Key.ToString(), GetJson(emdict.Value, deep));
				}
				return dict;
			}

			Arr arr = new Arr(10);
			while (em.MoveNext())
			{
				if (em.Current == null) arr.Add(Null.INSTANCE);
				else arr.Add(GetJson(em.Current, deep));
			}
			return arr;
		}
		/// <summary>
		/// 获取json对象
		/// 不解析子object
		/// </summary>
		/// <param name="obj"></param>
		/// <returns></returns>
		public static Json GetJson(IEnumerable obj) { return GetJson(obj, 0); }

		/// <summary>
		/// 获取json对象
		/// </summary>
		/// <param name="obj"></param>
		/// <param name="deep">对object的解析深度，0不解析</param>
		/// <returns></returns>
		public static Json GetJson(object obj, int deep)
		{
			if (obj == null) return Null.INSTANCE;
			if (deep < 0) return new String(obj.ToString());

			if (obj is Json) return obj as Json;
			if (obj is int) return GetJson((int)obj);
			if (obj is bool) return GetJson((bool)obj);
			if (obj is string) return GetJson((string)obj);
			if (obj is float) return GetJson((float)obj);
			if (obj is long) return GetJson((long)obj);
			if (obj is double) return GetJson((double)obj);
			if (obj is decimal) return GetJson((decimal)obj);
			if (obj is DateTime) return GetJson((DateTime)obj);
			if (obj is IConvertible) return GetJson((IConvertible)obj);
			if (obj is IEnumerable) return GetJson((IEnumerable)obj, deep);
			return _GETObjPropFields(obj, deep);
		}
		/// <summary>
		/// 获取json对象
		/// 不解析子object
		/// </summary>
		/// <param name="obj"></param>
		/// <returns></returns>
		public static Json GetJson(object obj) { return GetJson(obj, 0); }
		private static Json _GETObjPropFields(object obj, int deep)
		{
			System.Reflection.MemberInfo[] arr = obj.GetType().GetMembers(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy);
			Obj jo = new jsonar.Obj(arr.Length);
			System.Reflection.PropertyInfo p;
			System.Reflection.ParameterInfo[] pms;
			foreach (System.Reflection.MemberInfo m in arr)
			{
				if (m.MemberType == System.Reflection.MemberTypes.Field)
				{
					try { jo.Add(m.Name, GetJson(((System.Reflection.FieldInfo)m).GetValue(obj), deep - 1)); }
					catch (Exception e0) { jo.Add(m.Name, e0.Message); }
				}
				if (m.MemberType == System.Reflection.MemberTypes.Property)
				{
					p = (System.Reflection.PropertyInfo)m;
					if (!p.CanRead) continue;
					pms = p.GetIndexParameters(); if (pms != null && pms.Length > 0) continue;
					try { jo.Add(p.Name, GetJson(p.GetValue(obj, null), deep - 1)); }
					catch (Exception e) { jo.Add(p.Name, e.Message); }
				}
			}
			return jo;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="str">json格式的字符串：[]或{}</param>
		/// <returns></returns>
		public static Json Parse(string str) {
			if (str == null) return Null.INSTANCE;
			str = str.Trim();
			if (str.Length < 1) return Null.INSTANCE;
			int idx = -1;
			return Parser.ParseJson(str, ref idx);
		}

		public virtual Json getChild(int index) { return Null.INSTANCE; }
		public virtual Json getChild(string name) { return Null.INSTANCE; }


		#region GetValue
		public virtual Obj getValue(Obj dft) { return dft; }
		public virtual Arr getValue(Arr dft) { return dft; }
		public virtual int getValue(int dft) { return dft; }
		public virtual uint getValue(uint dft) { return dft; }
		public virtual long getValue(long dft) { return dft; }
		public virtual float getValue(float dft) { return dft; }
		public virtual double getValue(double dft) { return dft; }
		public virtual decimal getValue(decimal dft) { return dft; }
		public virtual bool getValue(bool dft) { return dft; }
		public virtual string getValue(string dft) { return dft; }
		#endregion

		/// <summary>
		/// 子节点的数量
		/// </summary>
		/// <returns></returns>
		public virtual int Count() { return 0; }

		public virtual bool hasChild() { return false; }
		public override abstract string ToString();
		public virtual string toHtml() { return this.ToString(); }
	}
}
